import 'package:flutter_test/flutter_test.dart';
import 'package:awak/common/models/content.dart';
import 'package:awak/common/models/review.dart';

void main() {
  group('Content Sorting Tests', () {
    late List<Content> testContents;
    late List<Review> testReviews;

    setUp(() {
      final now = DateTime.now();
      
      // 创建测试内容，按发布时间排序
      testContents = [
        Content(
          id: 1,
          picture: 'content1.jpg',
          description: 'Oldest content',
          userId: 1,
          topicId: 1,
          publishedAt: now.subtract(Duration(days: 10)), // 最旧
        ),
        Content(
          id: 2,
          picture: 'content2.jpg',
          description: 'Middle content',
          userId: 2,
          topicId: 1,
          publishedAt: now.subtract(Duration(days: 5)), // 中间
        ),
        Content(
          id: 3,
          picture: 'content3.jpg',
          description: 'Newest content',
          userId: 3,
          topicId: 1,
          publishedAt: now.subtract(Duration(hours: 1)), // 最新
        ),
      ];

      // 创建测试评论，content1有最多评论，content3有最少评论
      testReviews = [
        // content1 有 3 条评论 (最热)
        Review(id: 1, content: 'Review 1 for content 1', userId: 1, contentId: 1),
        Review(id: 2, content: 'Review 2 for content 1', userId: 2, contentId: 1),
        Review(id: 3, content: 'Review 3 for content 1', userId: 3, contentId: 1),
        
        // content2 有 2 条评论 (中等)
        Review(id: 4, content: 'Review 1 for content 2', userId: 1, contentId: 2),
        Review(id: 5, content: 'Review 2 for content 2', userId: 2, contentId: 2),
        
        // content3 有 1 条评论 (最少)
        Review(id: 6, content: 'Review 1 for content 3', userId: 1, contentId: 3),
      ];
    });

    test('Content model should include publishedAt field', () {
      final content = Content(
        id: 1,
        picture: 'test.jpg',
        description: 'Test description',
        userId: 1,
        topicId: 1,
        publishedAt: DateTime.now(),
      );

      expect(content.publishedAt, isA<DateTime>());
      expect(content.picture, 'test.jpg');
      expect(content.description, 'Test description');
    });

    test('Content toMap should include publishedAt', () {
      final now = DateTime.now();
      final content = Content(
        id: 1,
        picture: 'test.jpg',
        description: 'Test description',
        userId: 1,
        topicId: 1,
        publishedAt: now,
      );

      final map = content.toMap();
      expect(map['publishedAt'], now.millisecondsSinceEpoch);
      expect(map['picture'], 'test.jpg');
      expect(map['description'], 'Test description');
    });

    test('Content fromMap should include publishedAt', () {
      final now = DateTime.now();
      final map = {
        'id': 1,
        'picture': 'test.jpg',
        'description': 'Test description',
        'userId': 1,
        'topicId': 1,
        'publishedAt': now.millisecondsSinceEpoch,
      };

      final content = Content.fromMap(map);
      expect(content.publishedAt?.millisecondsSinceEpoch, now.millisecondsSinceEpoch);
      expect(content.picture, 'test.jpg');
      expect(content.description, 'Test description');
    });

    test('Content copyWith should handle publishedAt', () {
      final original = Content(
        id: 1,
        picture: 'original.jpg',
        description: 'Original description',
        userId: 1,
        topicId: 1,
        publishedAt: DateTime.now(),
      );

      final newTime = DateTime.now().add(Duration(hours: 1));
      final updated = original.copyWith(
        publishedAt: newTime,
        description: 'Updated description',
      );

      expect(updated.publishedAt, newTime);
      expect(updated.description, 'Updated description');
      expect(updated.picture, 'original.jpg'); // 未更改的字段保持原值
    });

    test('should sort contents by latest (publishedAt DESC)', () {
      // 按最新时间排序
      final sortedByLatest = List<Content>.from(testContents);
      sortedByLatest.sort((a, b) => b.publishedAt!.compareTo(a.publishedAt!));

      // 验证排序结果：最新的在前面
      expect(sortedByLatest[0].id, 3); // 最新的content
      expect(sortedByLatest[1].id, 2); // 中间的content
      expect(sortedByLatest[2].id, 1); // 最旧的content

      expect(sortedByLatest[0].description, 'Newest content');
      expect(sortedByLatest[2].description, 'Oldest content');
    });

    test('should sort contents by hot (review count DESC)', () {
      // 计算每个content的评论数量
      final contentReviewCounts = <int, int>{};
      for (final review in testReviews) {
        contentReviewCounts[review.contentId] = 
            (contentReviewCounts[review.contentId] ?? 0) + 1;
      }

      // 按评论数量排序
      final sortedByHot = List<Content>.from(testContents);
      sortedByHot.sort((a, b) {
        final aCount = contentReviewCounts[a.id] ?? 0;
        final bCount = contentReviewCounts[b.id] ?? 0;
        if (bCount != aCount) {
          return bCount.compareTo(aCount); // 评论数量降序
        }
        return b.publishedAt!.compareTo(a.publishedAt!); // 时间降序作为次要排序
      });

      // 验证排序结果：评论最多的在前面
      expect(sortedByHot[0].id, 1); // content1 有3条评论
      expect(sortedByHot[1].id, 2); // content2 有2条评论
      expect(sortedByHot[2].id, 3); // content3 有1条评论

      // 验证评论数量
      expect(contentReviewCounts[1], 3);
      expect(contentReviewCounts[2], 2);
      expect(contentReviewCounts[3], 1);
    });

    test('should handle contents with same review count by publishedAt', () {
      // 创建两个有相同评论数量的content
      final now = DateTime.now();
      final content1 = Content(
        id: 1,
        picture: 'content1.jpg',
        description: 'Content 1',
        userId: 1,
        topicId: 1,
        publishedAt: now.subtract(Duration(hours: 2)), // 较旧
      );
      final content2 = Content(
        id: 2,
        picture: 'content2.jpg',
        description: 'Content 2',
        userId: 2,
        topicId: 1,
        publishedAt: now.subtract(Duration(hours: 1)), // 较新
      );

      final contents = [content1, content2];
      
      // 假设两个content都有1条评论
      final reviewCounts = {1: 1, 2: 1};
      
      // 按热度排序（评论数量相同时按时间排序）
      contents.sort((a, b) {
        final aCount = reviewCounts[a.id] ?? 0;
        final bCount = reviewCounts[b.id] ?? 0;
        if (bCount != aCount) {
          return bCount.compareTo(aCount);
        }
        return b.publishedAt!.compareTo(a.publishedAt!); // 时间降序
      });

      // 评论数量相同时，较新的应该在前面
      expect(contents[0].id, 2); // content2 更新
      expect(contents[1].id, 1); // content1 较旧
    });

    test('should handle null publishedAt gracefully', () {
      final contentWithoutTime = Content(
        id: 1,
        picture: 'test.jpg',
        description: 'Test description',
        userId: 1,
        topicId: 1,
        publishedAt: null,
      );

      expect(contentWithoutTime.publishedAt, null);
      
      final map = contentWithoutTime.toMap();
      expect(map['publishedAt'], null);
    });

    test('should validate sorting logic consistency', () {
      // 验证排序逻辑的一致性
      
      // Latest排序：按时间降序
      final latestSorted = List<Content>.from(testContents);
      latestSorted.sort((a, b) => b.publishedAt!.compareTo(a.publishedAt!));
      
      // 验证时间顺序
      for (int i = 0; i < latestSorted.length - 1; i++) {
        expect(
          latestSorted[i].publishedAt!.isAfter(latestSorted[i + 1].publishedAt!) ||
          latestSorted[i].publishedAt!.isAtSameMomentAs(latestSorted[i + 1].publishedAt!),
          true,
          reason: 'Latest sorting should be in descending order by publishedAt'
        );
      }
      
      // Hot排序验证
      final reviewCounts = <int, int>{};
      for (final review in testReviews) {
        reviewCounts[review.contentId] = (reviewCounts[review.contentId] ?? 0) + 1;
      }
      
      final hotSorted = List<Content>.from(testContents);
      hotSorted.sort((a, b) {
        final aCount = reviewCounts[a.id] ?? 0;
        final bCount = reviewCounts[b.id] ?? 0;
        if (bCount != aCount) {
          return bCount.compareTo(aCount);
        }
        return b.publishedAt!.compareTo(a.publishedAt!);
      });
      
      // 验证热度排序
      for (int i = 0; i < hotSorted.length - 1; i++) {
        final currentCount = reviewCounts[hotSorted[i].id] ?? 0;
        final nextCount = reviewCounts[hotSorted[i + 1].id] ?? 0;
        expect(
          currentCount >= nextCount,
          true,
          reason: 'Hot sorting should be in descending order by review count'
        );
      }
    });
  });
}
